package cn.itsource.user.service.impl;

import cn.itsource.dto.BinderDto;
import cn.itsource.user.WechatConstant;
import cn.itsource.user.domain.TLogininfo;
import cn.itsource.user.domain.TUser;
import cn.itsource.user.domain.TWxuser;
import cn.itsource.user.domain.Wechat;
import cn.itsource.user.mapper.LogininfoMapper;
import cn.itsource.user.mapper.UserMapper;
import cn.itsource.user.mapper.WxuserMapper;
import cn.itsource.user.service.IWechatService;
import cn.itsource.utils.AjaxResult;
import cn.itsource.utils.HttpClient;
import cn.itsource.utils.MD5;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.swing.*;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Service
@Transactional
public class WechatServiceImpl implements IWechatService {
    @Autowired
    private WxuserMapper wxuserMapper;
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private LogininfoMapper logininfoMapper;

    /**
     * 作用：根据授权码code来获取access_token令牌
     *
     * @param map
     * @return
     */
    @Override
    public AjaxResult handleCallback(Map map) {
        String code = map.get("code").toString();
        //1. 根据授权码来获取到令牌
        String token_url = WechatConstant.TOKEN_URL.replace("APPID", WechatConstant.APPID).replace("SECRET", WechatConstant.SECRET).replace("CODE", code);
        //因为是在后台进行url请求，所以需要用到一个工具：http请求的工具类
        HttpClient httpClient = new HttpClient(token_url);
        httpClient.get();
        String token_url_content = httpClient.getContent();//请求后，获取的结果
        // {"access_token":"46_lPBTz35Lgsd66lY7y4b2G3y16bZD2Y5w4PUiIFO653zZvPx3XOPx4tpnl7EqxeBdHDiyM5SOVA4lz7OzdkGNMpDObLqVAV8FEsAbgRPVTjk","expires_in":7200,"refresh_token":"46_OHyIyS45yLpGw7If9Cl1dQJWVgGwif5rfIZKz-n7zLCGBDa-Xu-E9gS-In5BavVJO6fyvtXnRpTx2oj6rgCwmdSj52PnN-bNlY3xAPvcrXA","openid":"oa9wA00KpxKdb7xASEJKqN3qdpJA","scope":"snsapi_login","unionid":"ovnCWw0qS-8SJO9qwZdlLfCqHQCU"}
        //2. 根据令牌来查询微信登录用户的信息
        JSONObject tokenJson = JSONObject.parseObject(token_url_content);
        //从tokenjson中获取查询微信用户信息的2个必传参数：access_token + openid（当前登录的微信的（加密）微信号）
        String accessToken = tokenJson.getString("access_token");
        String openid = tokenJson.getString("openid");
        String userinfo_url = WechatConstant.USERINFO_URL.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openid);
        httpClient = new HttpClient(userinfo_url);
        httpClient.get();
        String userInfoJson = httpClient.getContent();
        System.out.println("userjson====>" + userInfoJson);
        //进行绑定业务操作前，先将获取的微信用户信息，保存到一个对象中
        //注意：一定不要修改Wechat属性中的属性名。即：对象中的属性名必须与json中每一个key一一对应
        Wechat wechat = JSONObject.parseObject(userInfoJson, Wechat.class);

        //业务梳理之后的代码改造业务
//        1.判断t_wxuser是否存在openid，不存在，直接跳绑定页面
        TWxuser wxuser = wxuserMapper.findWxuserByOpenId(wechat.getOpenid());
        if (wxuser == null || StringUtils.isBlank(wxuser.getOpenid())) {
            // 如果不存在，新增
            wxuser = new TWxuser();
            wxuser.setOpenid(wechat.getOpenid());
            wxuser.setNickname(wechat.getNickname());
            wxuser.setSex(wechat.getSex());
            wxuser.setAddress(wechat.getCountry() + "-" + wechat.getProvince() + "-" + wechat.getCity());
            wxuser.setHeadimgurl(wechat.getHeadimgurl());
            wxuser.setUnionid(wechat.getUnionid());
            //执行添加操作
            wxuserMapper.insert(wxuser);
            return AjaxResult.error().setData(openid);
        }

//        2.判断user_id是否存在,不存在，直接跳绑定页面
        if (wxuser.getUserId() == null) {
            return AjaxResult.error().setData(openid);
        }
//        3. t_user表是否可查到数据，不存在，直接跳绑定页面
        TUser tUser = userMapper.selectByPrimaryKey(wxuser.getUserId());
        if (tUser == null) {
            return AjaxResult.error().setData(openid);
        }
//        4. 判断phone是否存在，不存在，直接跳绑定页面
        if (StringUtils.isBlank(tUser.getPhone())) {
            return AjaxResult.error().setData(openid);
        }
//        5. 如果上面4个判断，都没进入，则直接跳首页（说明已经绑定过手机号）
        return AjaxResult.me().setData(newLoginUser(tUser));
    }

    private Map<String, Object> newLoginUser(TUser tUser) {
        //跳首页（1、生成token令牌；2.查询用户的信息）
        String token = UUID.randomUUID().toString();
        Map<String, Object> result = new HashMap<>();
        result.put("token", token);
        //为了安全起见，把前台不会用到铭感信息salt和password去空
        tUser.setPassword(null);
        result.put("loginUser", tUser);

        return result;
    }

    @Override
    public AjaxResult binder(BinderDto dto) {
        //此时，前端传递了2个重要的参数：
        //1.手机号phone；2.openid
        //1. 各种校验：手机号的校验；openid的非空校验
        // 略
        //2. 先判断t_user中，是否有这个手机号
        TUser user = userMapper.findByPhone(dto.getPhone());
        //3. 如果有，则直接获取它的id，关联到t_wxuser
        TWxuser wxuser = wxuserMapper.findWxuserByOpenId(dto.getOpenid());
        if (user == null) {
            //4. 如果没有，先要添加一条新数据到t_user
            user = new TUser();
            user.setPhone(dto.getPhone());
            user.setUsername(dto.getPhone());
            user.setState(TUser.STATE_ZHENGCHANG);
            user.setCreatetime(new Date());
            user.setHeadImg(wxuser.getHeadimgurl());
            //2021年6月21日：代码完善：在创建新user用户时，给一个默认密码：123
            String salt = MD5.getMD5(System.currentTimeMillis() + "");
            String pwd = MD5.getMD5(salt + "123");
            user.setSalt(salt);
            user.setPassword(pwd);
            userMapper.insert(user); //添加成功后，添加的数据主键，要能返回

            //如果是新增的用户，则需要同步添加一条数据到t_logininfo表中
            TLogininfo logininfo = new TLogininfo();
            logininfo.setUsername(user.getPhone());
            logininfo.setPhone(user.getPhone());
            logininfo.setDisable(true);
            logininfo.setType(false);
            logininfo.setSalt(user.getSalt());
            logininfo.setPassword(user.getPassword());
            logininfo.setLoginId(user.getId());
            logininfoMapper.insert(logininfo);
        }
        //5.再根据新增的t_user的主键，关联到t_wxuser
        //更新t_wxuser的关联字段user_id
        wxuser.setUserId(user.getId());
        wxuserMapper.updateByPrimaryKey(wxuser);
        return AjaxResult.me().setData(newLoginUser(user));
    }

}
